package com.robusta.app.web.controller;

import com.robusta.app.auth.api.AuthenticationFailedException;
import com.robusta.app.auth.api.UserAuthentication;
import com.robusta.app.domain.user.UserSession;
import com.robusta.app.web.auth.AuthenticationTokenStrategy;
import com.robusta.app.web.interceptor.AuthDisabled;
import com.robusta.app.web.model.LoginViewModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.http.HttpServletResponse;

@Controller
@RequestMapping("login")
@AuthDisabled
public class LoginController {
    private UserAuthentication authentication;
    private AuthenticationTokenStrategy tokenStrategy;

    @Autowired
    public LoginController(UserAuthentication authentication, AuthenticationTokenStrategy tokenStrategy) {
        this.authentication = authentication;
        this.tokenStrategy = tokenStrategy;
    }

    @RequestMapping(produces = MediaType.TEXT_HTML_VALUE, method = RequestMethod.GET)
    public String displayPage(ModelMap modelMap) {
        modelMap.put("loginModel", new LoginViewModel());
        return "login";
    }

    @RequestMapping(method = RequestMethod.POST, value = "authentication")
    public String loginWithCredentials(@ModelAttribute("loginModel") LoginViewModel model, BindingResult errors, HttpServletResponse response) {
        UserSession userSession;
        try {
            userSession = authentication.authenticateAndCreateUserSession(model.getUserName(), model.getPassword());
        } catch (AuthenticationFailedException e) {
            return backToLoginPageWithAuthenticationFailed(errors);
        }
        tokenStrategy.saveAuthenticationToken(userSession.authentication().authToken(), response);
        return "redirect:/home.html";
    }

    private String backToLoginPageWithAuthenticationFailed(BindingResult errors) {
        errors.reject("AUTH-101", "Login failed. Please try again...");
        return "login";
    }
}
